﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ValiVIN.Manufacturer
{
    internal class Lamborghini : IVINManufacturer
    {
        //Example VIN: ZHWGU22TX8LA06155

        //Earliest Year
        //Lamborghini got a new WMI in 2003
        private static readonly int _EARLIEST_Year = 2003;


        #region Singleton

        static readonly Lamborghini _instance = new Lamborghini();

        public static Lamborghini Instance
        {
            get { return _instance; }
        }

        #endregion

        private void CheckYear(VINumber vin)
        {
            if (vin.Year1 < _EARLIEST_Year)
            {
                vin.Year1 = vin.Year2;
                vin.Year2 = 0;
            }
        }

        #region IVINManufacturer Members

        public bool Decode(VINumber vin)
        {

            CheckYear(vin);
            GetPlant(vin);
            GetModel(vin);
            GetSerialNumber(vin);
            GetMarket(vin);
            GetEngine(vin);
            GetFeatures(vin);
            return true;
        }

        private void GetFeatures(VINumber vin)
        {
           // Digit 8 = Features (M=6sp, N=low ratio 6sp, S=egear, T=low ratio egear, V=6sp, Z=egear, G=6sp, H=egear)
            string key = "Features";
            string value = string.Empty;
            string v = vin.VIN.Substring(7, 1);

            switch (v)
            {
                case "M":
                case "V":
                case "G":
                    value = "6 Speed";
                    break;
                case "N":
                    value = "Low Ratio 6 Speed";
                    break;
                case "S":
                case "Z":
                case "H":
                    value = "E-Gear";
                    break;
                case "T":
                    value = "Low Ratio E-Gear";
                    break;
            }

            if (!string.IsNullOrEmpty(value))
            {
                vin.ManufacturerSpecifics[key] = value;
            }
        }

        private void GetEngine(VINumber vin)
        {
            //Digit 7 = Engine (1=500HPv10, 2=520HPv10, 3=530HPv10, 4=560HP/5.2v10, B=550HP/5.2v10, 6=6.2v12, 7=6.5v12)
            string key = "Engine";
            string value = string.Empty;
            string v = vin.VIN.Substring(6, 1);

            switch (v)
            {
                case "1":
                    value = "500HPv10";
                    break;
                case "2":
                    value = "520HPv10";
                    break;
                case "3":
                    value = "530HPv10";
                    break;
                case "4":
                    value = "560HPv10/5.2v10";
                    break;
                case "B":
                    value = "550HP/5.2v10";
                    break;
                case "6":
                    value = "6.2v12";
                    break;
                case "7":
                    value = "6.5v12";
                    break;
            }

            if (!string.IsNullOrEmpty(value))
            {
                vin.ManufacturerSpecifics[key] = value;
            }
        }

        private void GetMarket(VINumber vin)
        {
            //Digit 5 = Market (C=Canada, E=Europe, U=USA etc)
            string key = "Market";
            string value = string.Empty;
            string v = vin.VIN.Substring(6, 1);

            switch (v)
            {
                case "C":
                    value = "Canada";
                    break;
                case "E":
                    value = "Europe";
                    break;
                case "U":
                case "A":
                    value = "USA";
                    break;
                case "0":
                    value = "Other";
                    break;
            }

            if (!string.IsNullOrEmpty(value))
            {
                vin.ManufacturerSpecifics[key] = value;
            }
        }

        private void GetSerialNumber(VINumber vin)
        {
            //12 - 17
            string serialNum = vin.VIN.Substring(11, 6);
            vin.SerialNumber = serialNum;
        }

        private void GetModel(VINumber vin)
        {
            string key = "Model";
            string model = string.Empty;
            string m = vin.VIN.Substring(3, 1); //digit 4
            //Model (B=Murci, G=Gallardo)

            string bodyKey = "Body";
            string body = string.Empty;
            if (m == "B")
            {
                model = "Murciélago";
                body= GetBodyMurci(vin);
            }
            else if (m == "G")
            {
                model = "Gallardo";
                body = GetBodyGallardo(vin);
            }

            if (!string.IsNullOrEmpty(model))
            {
                vin.ManufacturerSpecifics[key] = model;
            }

            if (!string.IsNullOrEmpty(body))
            {
                vin.ManufacturerSpecifics[bodyKey] = body;
            }
        }

        private string GetBodyGallardo(VINumber vin)
        {
            //Body (Gallardo - 1=Coupe, 2=Spyder, 4=Superleggera, 5=LP5x0 Coupe, 6=LP560 Spyder)
            string body = string.Empty;
            string b = vin.VIN.Substring(5, 1); //digit 6

            switch (b)
            {
                case "1":
                    body = "Coupe";
                    break;
                case "2":
                    body = "Spyder";
                    break;
                case "4":
                    body = "Superleggera";
                    break;
                case "5":
                    body = "LP5x0 Coupe";
                    break;
                case "6":
                    body = "LP560 Spyder";
                    break;
            }

            return body;
        }

        private string GetBodyMurci(VINumber vin)
        {
            //Body (Murci - 1=Coupe, 2=Roadster, 3=LP640 Coupe, 4=LP640 Roadster, 7=Reventon, 8=LP670-4 SV)
            string body = string.Empty;
            string b = vin.VIN.Substring(5, 1); //digit 6

            switch (b)
            {
                case "1":
                    body = "Coupe";
                    break;
                case "2":
                    body = "Roadster";
                    break;
                case "3":
                    body = "LP640 Coupe";
                    break;
                case "4":
                    body = "LP640 Roadster";
                    break;
                case "7":
                    body = "Reventon";
                    break;
                case "8":
                    body = "LP670-4 SV";
                    break;
            }

            return body;
        }

        private void GetPlant(VINumber vin)
        {
            // Plant (L=Sant'Agata Bolognese - Bologna Italia)
            string plant = string.Empty;
            string p = vin.VIN.Substring(10, 1);
            if (p == "L")
            {
                plant = "Sant'Agata Bolognese - Bologna Italia";
            }

            vin.Plant = plant;
        }

        public string ManufacturerName(string vin)
        {
            return "Lamborghini";
        }

        #endregion
    }
}
